import fastapi, os, logging
from .render import Text2ImgRender, ScreenshotOptions
from dataclasses import dataclass
import markdown
from markdown.extensions.tables import TableExtension  # 关键扩展
import re

def markdwon_to_html(markdown_text):

    # 预处理：将单元格内的换行符转为HTML标签
    md_content = re.sub(r'(\|[^\n\|]+)\n(?=[^\|])', r'\1<br>', markdown_text)
    
    # 启用表格扩展和额外配置
    # Convert the Markdown text to HTML
    html_content = markdown.markdown(
        md_content,
        extensions=[
            TableExtension(use_align_attribute=True),  # 支持对齐属性
            'md_in_html'  # 允许HTML标签嵌套
        ],
        tab_length=2  # 解决|符号对齐问题
    )
    
    # 创建带样式的完整HTML文档
    html = """
    <!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <style>
    :root {
      --primary: #2c3e50;
      --secondary: #3498db;
      --accent: #9b59b6;
      --light: #ecf0f1;
      --dark: #34495e;
      --success: #2ecc71;
      --warning: #f39c12;
      --danger: #e74c3c;
      --radius: 8px;
      --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      --transition: all 0.3s ease;
    }
    
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif;
      line-height: 1.8;
      color: #333;
      background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%);
      margin: 0;
      min-height: 100vh;
      height: 100%;
    }

    div {
      padding: 20px;
      box-sizing: border-box;
    }
    
    .container {
      max-width: 900px;
      margin: 40px auto;
      background: white;
      border-radius: var(--radius);
      box-shadow: var(--shadow);
      overflow: hidden;
      padding: 30px;
    }
    
    h1, h2, h3, h4, h5, h6 {
      font-weight: 700;
      margin-top: 1.5em;
      margin-bottom: 0.8em;
      color: var(--primary);
      position: relative;
      padding-bottom: 8px;
    }
    
    h1 {
      font-size: 2.5rem;
      border-bottom: 3px solid var(--secondary);
    }
    
    h2 {
      font-size: 2rem;
      border-bottom: 2px solid var(--accent);
    }
    
    h3 {
      font-size: 1.75rem;
      color: var(--dark);
    }
    
    h4 {
      font-size: 1.5rem;
    }
    
    h5 {
      font-size: 1.25rem;
    }
    
    h6 {
      font-size: 1rem;
      color: var(--dark);
    }
    
    p {
      margin-bottom: 1.2em;
    }
    
    a {
      color: var(--secondary);
      text-decoration: none;
      transition: var(--transition);
    }
    
    a:hover {
      color: var(--accent);
      text-decoration: underline;
    }
    
    pre {
      background: #2d2d2d;
      color: #f8f8f2;
      padding: 20px;
      border-radius: var(--radius);
      overflow: auto;
      margin: 1.5em 0;
      box-shadow: var(--shadow);
      font-size: 0.95rem;
    }
    
    code {
      font-family: 'Fira Code', 'SFMono-Regular', Consolas, monospace;
      background: rgba(175, 184, 193, 0.2);
      color: #e45649;
      padding: 2px 6px;
      border-radius: 4px;
      font-size: 0.9em;
    }
    
    pre code {
      background: transparent;
      color: inherit;
      padding: 0;
      border-radius: 0;
    }
    
    table {
      width: 100%;
      border-collapse: collapse;
      margin: 1.5em 0;
      box-shadow: var(--shadow);
      border-radius: var(--radius);
      overflow: hidden;
    }
    
    th {
      background-color: var(--primary);
      color: white;
      text-align: left;
      font-weight: 600;
    }
    
    th, td {
      padding: 12px 16px;
      border: 1px solid #e1e4e8;
    }
    
    tr:nth-child(even) {
      background-color: #f8f9fa;
    }
    
    tr:hover {
      background-color: #e9f7fe;
      transition: var(--transition);
    }
    
    blockquote {
      border-left: 4px solid var(--secondary);
      background: #f8f9fa;
      padding: 15px 20px;
      margin: 1.5em 0;
      border-radius: 0 var(--radius) var(--radius) 0;
    }
    
    blockquote p {
      margin: 0;
      color: var(--dark);
      font-style: italic;
    }
    
    hr {
      border: 0;
      height: 1px;
      background: linear-gradient(to right, transparent, var(--secondary), transparent);
      margin: 2em 0;
    }
    
    @media (max-width: 768px) {
      .container {
        padding: 20px;
        margin: 20px;
      }
      
      h1 {
        font-size: 2rem;
      }
      
      h2 {
        font-size: 1.75rem;
      }
    }
  </style>
</head>
<body><div data-screenshot-container>""" + html_content +  \
"""</div></body>
</html>
    """
    return html
 
app = fastapi.FastAPI()
render = Text2ImgRender()

@dataclass
class Result():
    code: int
    message: str
    data: dict

@app.get("/text2img/data/{id}")
async def text2img_image(id: str):
    pic = f"data/{id}"
    if os.path.exists(pic):
        return fastapi.responses.FileResponse(pic, media_type="image/jpeg")
    else:
        return Result(code=1, message="file not found", data={})

@app.post("/text2img/generate")
async def text2img(request: fastapi.Request):
    '''
    html: str
    options: ScreenshotOptions
    '''
    
    data = await request.json()
    is_json_return = False
    if "json" in data:
        is_json_return = data["json"]
    if 'tmpl' in data or 'tmplname' in data:
        tmpl = markdwon_to_html(data['tmpldata']['text'])
        ttext = {"text": ""}
        html_file_path, abs_path = await render.from_jinja_template(tmpl, ttext)
    elif 'html' in data:
        html = data["html"]
        html_file_path, abs_path = await render.from_html(html)
    else:
        return Result(code=1, message="html or tmpl not found", data={})
    options = ScreenshotOptions(**data["options"]) if "options" in data else ScreenshotOptions()
    pic = await render.html2pic(abs_path, options)
    if is_json_return:
        return Result(code=0, message="success", data={
            "id": pic
        })
    else:
        return fastapi.responses.FileResponse(pic, media_type="image/jpeg")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8999)
